home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 090 / me39src1.arc / SPAWN.C < prev    next >
C/C++ Source or Header  |  1987-07-12  |  17KB  |  636 lines

  1. /*    Spawn:    various DOS access commands
  2.         for MicroEMACS
  3. */
  4.  
  5. #include        <stdio.h>
  6. #include    "estruct.h"
  7. #include        "edef.h"
  8.  
  9. #if     AMIGA
  10. #define  NEW   1006L
  11. #endif
  12.  
  13. #if        ST520 & MEGAMAX
  14. #include <osbind.h>
  15. #include <string.h>
  16. #define LOAD_EXEC 0     /* load and execute the program */
  17. char    *STcmd,        /* the command filename & path  */
  18.     *STargs,    /* command args (if any)        */
  19.     *STenv,        /* environment                  */
  20.     *STwork;    /* work area            */
  21. #endif
  22.  
  23. #if     VMS
  24. #define EFN     0                               /* Event flag.          */
  25.  
  26. #include        <ssdef.h>                       /* Random headers.      */
  27. #include        <stsdef.h>
  28. #include        <descrip.h>
  29. #include        <iodef.h>
  30.  
  31. extern  int     oldmode[3];                     /* In "termio.c"        */
  32. extern  int     newmode[3];                     /* In "termio.c"        */
  33. extern  short   iochan;                         /* In "termio.c"        */
  34. #endif
  35.  
  36. #if     V7 | USG | BSD
  37. #include        <signal.h>
  38. extern int vttidy();
  39. #endif
  40.  
  41. #if    MSDOS & (MSC | TURBO)
  42. #include    <process.h>
  43. #endif
  44.  
  45. /*
  46.  * Create a subjob with a copy of the command intrepreter in it. When the
  47.  * command interpreter exits, mark the screen as garbage so that you do a full
  48.  * repaint. Bound to "^X C". The message at the start in VMS puts out a newline.
  49.  * Under some (unknown) condition, you don't get one free when DCL starts up.
  50.  */
  51. spawncli(f, n)
  52. {
  53. #if     AMIGA
  54.         long newcli;
  55.  
  56. #endif
  57.  
  58. #if     V7 | USG | BSD
  59.         register char *cp;
  60.         char    *getenv();
  61. #endif
  62.  
  63.     /* don't allow this command if restricted */
  64.     if (restflag)
  65.         return(resterr());
  66.  
  67. #if    AMIGA
  68.         mlwrite("[Starting new CLI]");
  69.         sgarbf = TRUE;
  70.         Execute("NEWCLI \"CON:0/0/640/200/MicroEMACS Subprocess\"", 0L, 0L);
  71.         return(TRUE);
  72. #endif
  73.  
  74. #if     VMS
  75.         movecursor(term.t_nrow, 0);             /* In last line.        */
  76.         mlputs("[Starting DCL]\r\n");
  77.         TTflush();                          /* Ignore "ttcol".      */
  78.         sgarbf = TRUE;
  79.         return (sys(NULL));                     /* NULL => DCL.         */
  80. #endif
  81. #if     CPM
  82.         mlwrite("Not in CP/M-86");
  83. #endif
  84. #if    ST520
  85.     mlwrite("Not in TOS");
  86. #endif
  87. #if     MSDOS & (AZTEC | MSC | TURBO)
  88.         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  89.         TTflush();
  90.     TTkclose();
  91.     system("command.com");
  92.     TTkopen();
  93.         sgarbf = TRUE;
  94.         return(TRUE);
  95. #endif
  96. #if     MSDOS & LATTICE
  97.         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  98.         TTflush();
  99.     TTkclose();
  100.         sys("\\command.com", "");               /* Run CLI.             */
  101.     TTkopen();
  102.         sgarbf = TRUE;
  103.         return(TRUE);
  104. #endif
  105. #if     V7 | USG | BSD
  106.         movecursor(term.t_nrow, 0);             /* Seek to last line.   */
  107.         TTflush();
  108.         TTclose();                              /* stty to old settings */
  109.         if ((cp = getenv("SHELL")) != NULL && *cp != '\0')
  110.                 system(cp);
  111.         else
  112. #if    BSD
  113.                 system("exec /bin/csh");
  114. #else
  115.                 system("exec /bin/sh");
  116. #endif
  117.         sgarbf = TRUE;
  118.         sleep(2);
  119.         TTopen();
  120.         return(TRUE);
  121. #endif
  122. }
  123.  
  124. #if    BSD
  125.  
  126. bktoshell()        /* suspend MicroEMACS and wait to wake up */
  127. {
  128.     int pid;
  129.  
  130.     vttidy();
  131.     pid = getpid();
  132.     kill(pid,SIGTSTP);
  133. }
  134.  
  135. rtfrmshell()
  136. {
  137.     TTopen();
  138.     curwp->w_flag = WFHARD;
  139.     sgarbf = TRUE;
  140. }
  141. #endif
  142.  
  143. /*
  144.  * Run a one-liner in a subjob. When the command returns, wait for a single
  145.  * character to be typed, then mark the screen as garbage so a full repaint is
  146.  * done. Bound to "C-X !".
  147.  */
  148. spawn(f, n)
  149. {
  150.         register int    s;
  151.         char            line[NLINE];
  152.  
  153. #if    ST520 & MEGAMAX
  154.     int i,j,k;
  155.     char *sptr,*tptr;
  156. #endif
  157.  
  158. #if     AMIGA
  159.         long newcli;
  160. #endif
  161.  
  162.     /* don't allow this command if restricted */
  163.     if (restflag)
  164.         return(resterr());
  165.  
  166. #if    AMIGA
  167.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  168.                 return (s);
  169.         newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  170.         Execute(line, 0L, newcli);
  171.         Close(newcli);
  172.         tgetc();     /* Pause.               */
  173.         sgarbf = TRUE;
  174.         return(TRUE);
  175. #endif
  176. #if     ST520 & MEGAMAX
  177.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  178.                 return(s);
  179.     movecursor(term.t_nrow - 1, 0);
  180.     TTclose();
  181. /*
  182.  * break the line into the command and its args
  183.  * be cute about it, if there is no '.' in the filename, try
  184.  * to find .prg, .tos or .ttp in that order
  185.  * in any case check to see that the file exists before we run 
  186.  * amok
  187.  */
  188.     STenv = NULL;
  189.     if((tptr = index(&line[0],' ')) == NULL) { /* no args */
  190.         STcmd = (char *)malloc(strlen(line) + 1);
  191.         strcpy(STcmd,line);
  192.         STargs = NULL;
  193.     }
  194.     else {  /* seperate out the args from the command */
  195.         /* resist the temptation to do ptr arithmetic */
  196.         STcmd = (char *)malloc(strlen(line) + 1);
  197.         for(i = 0,sptr = &line[0]; sptr != tptr; sptr++,i++)
  198.             STcmd[i] = *sptr;
  199.         STcmd[i] = '\0';
  200.         for(; *tptr == ' ' || *tptr == '\t'; tptr++);
  201.         if(*tptr == '\0')
  202.             STargs = NULL;
  203.         else {
  204.             STargs = (char *)malloc(strlen(tptr) + 2);
  205. /* first byte of STargs is the length of the string */
  206.             STargs[0] = strlen(tptr);
  207.             STargs[1] = NULL; /* fake it for strcat */
  208.             strcat(STargs,tptr);
  209.         }
  210.     }
  211. /*
  212.  * before we issue the command look for the '.', if it's not there
  213.  * try adding .prg, .tos and .ttp to see if they exist, if not
  214.  * issue the command as is
  215.  */
  216.     if((tptr = index(STcmd,'.')) == NULL) {
  217.          STwork = (char *)malloc(strlen(STcmd) + 4);
  218.          strcpy(STwork,STcmd);
  219.          strcat(STwork,".prg");
  220.          tptr = index(STwork,'.');
  221.          if(Fsfirst(1,STwork) != 0) { /* try .tos */
  222.              strcpy(tptr,".tos");
  223.              if(Fsfirst(1,STwork) != 0) { /* try .ttp */
  224.                  strcpy(tptr,".ttp");
  225.                  if(Fsfirst(1,STwork) != 0) /* never mind */
  226.                      *STwork = NULL;
  227.                  }
  228.              }
  229.      }
  230.      if(*STwork != NULL)
  231.             Pexec(LOAD_EXEC,STwork,STargs,STenv);         
  232.     else
  233.             Pexec(LOAD_EXEC,STcmd,STargs,STenv);
  234.     TTopen();
  235.         mlputs("\r\n\n[End]");                  /* Pause.               */
  236.         TTgetc();                 /* Pause.               */
  237.         sgarbf = TRUE;
  238.         return (TRUE);
  239. #endif
  240. #if     VMS
  241.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  242.                 return (s);
  243.         TTputc('\n');                /* Already have '\r'    */
  244.         TTflush();
  245.         s = sys(line);                          /* Run the command.     */
  246.         mlputs("\r\n\n[End]");                  /* Pause.               */
  247.         TTflush();
  248.         tgetc();
  249.         sgarbf = TRUE;
  250.         return (s);
  251. #endif
  252. #if     CPM
  253.         mlwrite("Not in CP/M-86");
  254.         return (FALSE);
  255. #endif
  256. #if     MSDOS | (ST520 & LATTICE)
  257.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  258.                 return(s);
  259.     movecursor(term.t_nrow - 1, 0);
  260.     TTkclose();
  261.         system(line);
  262.     TTkopen();
  263.     /* if we are interactive, pause here */
  264.     if (clexec == FALSE) {
  265.             mlputs("\r\n\n[End]");
  266.             tgetc();
  267.         }
  268.         sgarbf = TRUE;
  269.         return (TRUE);
  270. #endif
  271. #if     V7 | USG | BSD
  272.         if ((s=mlreply("!", line, NLINE)) != TRUE)
  273.                 return (s);
  274.         TTputc('\n');                /* Already have '\r'    */
  275.         TTflush();
  276.         TTclose();                              /* stty to old modes    */
  277.         system(line);
  278.         TTopen();
  279.         mlputs("[End]");                        /* Pause.               */
  280.         TTflush();
  281.         while ((s = tgetc()) != '\r' && s != ' ')
  282.                 ;
  283.         sgarbf = TRUE;
  284.         return (TRUE);
  285. #endif
  286. }
  287.  
  288. /*
  289.  * Pipe a one line command into a window
  290.  * Bound to ^X @
  291.  */
  292. pipecmd(f, n)
  293. {
  294.         register int    s;    /* return status from CLI */
  295.     register WINDOW *wp;    /* pointer to new window */
  296.     register BUFFER *bp;    /* pointer to buffer to zot */
  297.         char    line[NLINE];    /* command line send to shell */
  298.     static char bname[] = "command";
  299.  
  300. #if    AMIGA
  301.     static char filnam[] = "ram:command";
  302.         long newcli;
  303. #else
  304.     static char filnam[NSTRING] = "command";
  305. #endif
  306.  
  307. #if    MSDOS
  308.     char *tmp;
  309.     char *getenv();
  310.     FILE *fp;
  311.     FILE *fopen();
  312. #endif
  313.  
  314.     /* don't allow this command if restricted */
  315.     if (restflag)
  316.         return(resterr());
  317.  
  318. #if    MSDOS
  319.     if ((tmp = getenv("TMP")) == NULL)
  320.         strcpy(filnam, "command");
  321.     else {
  322.         strcpy(filnam, tmp);
  323.                 strcat(filnam,"\\command");
  324.         }
  325. #endif
  326.  
  327. #if     VMS
  328.     mlwrite("Not availible under VMS");
  329.     return(FALSE);
  330. #endif
  331. #if     CPM
  332.         mlwrite("Not availible under CP/M-86");
  333.         return(FALSE);
  334. #endif
  335.  
  336.     /* get the command to pipe in */
  337.         if ((s=mlreply("@", line, NLINE)) != TRUE)
  338.                 return(s);
  339.  
  340.     /* get rid of the command output buffer if it exists */
  341.         if ((bp=bfind(bname, FALSE, 0)) != FALSE) {
  342.         /* try to make sure we are off screen */
  343.         wp = wheadp;
  344.         while (wp != NULL) {
  345.             if (wp->w_bufp == bp) {
  346.                 onlywind(FALSE, 1);
  347.                 break;
  348.             }
  349.             wp = wp->w_wndp;
  350.         }
  351.         if (zotbuf(bp) != TRUE)
  352.  
  353.             return(FALSE);
  354.     }
  355.  
  356. #if     AMIGA
  357.         newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  358.     strcat(line, " >");
  359.     strcat(line, filnam);
  360.         Execute(line, 0L, newcli);
  361.     s = TRUE;
  362.         Close(newcli);
  363.         sgarbf = TRUE;
  364. #endif
  365. #if     MSDOS
  366.     strcat(line," >>");
  367.     strcat(line,filnam);
  368.     movecursor(term.t_nrow - 1, 0);
  369.     TTkclose();
  370.         system(line);
  371.     TTkopen();
  372.         sgarbf = TRUE;
  373.     if ((fp = fopen(filnam, "r")) == NULL) {
  374.         s = FALSE;
  375.     } else {
  376.         fclose(fp);
  377.         s = TRUE;
  378.     }
  379. #endif
  380. #if     V7 | USG | BSD
  381.         TTputc('\n');                /* Already have '\r'    */
  382.         TTflush();
  383.         TTclose();                              /* stty to old modes    */
  384.     strcat(line,">");
  385.     strcat(line,filnam);
  386.         system(line);
  387.         TTopen();
  388.         TTflush();
  389.         sgarbf = TRUE;
  390.         s = TRUE;
  391. #endif
  392.  
  393.     if (s != TRUE)
  394.         return(s);
  395.  
  396.     /* split the current window to make room for the command output */
  397.     if (splitwind(FALSE, 1) == FALSE)
  398.             return(FALSE);
  399.  
  400.     /* and read the stuff in */
  401.     if (getfile(filnam, FALSE) == FALSE)
  402.         return(FALSE);
  403.  
  404.     /* make this window in VIEW mode, update all mode lines */
  405.     curwp->w_bufp->b_mode |= MDVIEW;
  406.     wp = wheadp;
  407.     while (wp != NULL) {
  408.         wp->w_flag |= WFMODE;
  409.         wp = wp->w_wndp;
  410.     }
  411.  
  412.     /* and get rid of the temporary file */
  413.     unlink(filnam);
  414.     return(TRUE);
  415. }
  416.  
  417. /*
  418.  * filter a buffer through an external DOS program
  419.  * Bound to ^X #
  420.  */
  421. filter(f, n)
  422.  
  423. {
  424.         register int    s;    /* return status from CLI */
  425.     register BUFFER *bp;    /* pointer to buffer to zot */
  426.         char line[NLINE];    /* command line send to shell */
  427.     char tmpnam[NFILEN];    /* place to store real file name */
  428.     static char bname1[] = "fltinp";
  429.  
  430. #if    AMIGA
  431.     static char filnam1[] = "ram:fltinp";
  432.     static char filnam2[] = "ram:fltout";
  433.         long newcli;
  434. #else
  435.     static char filnam1[] = "fltinp";
  436.     static char filnam2[] = "fltout";
  437. #endif
  438.  
  439.     /* don't allow this command if restricted */
  440.     if (restflag)
  441.         return(resterr());
  442.  
  443.     if (curbp->b_mode&MDVIEW)    /* don't allow this command if    */
  444.         return(rdonly());    /* we are in read only mode    */
  445.  
  446. #if     VMS
  447.     mlwrite("Not availible under VMS");
  448.     return(FALSE);
  449. #endif
  450. #if     CPM
  451.         mlwrite("Not availible under CP/M-86");
  452.         return(FALSE);
  453. #endif
  454.  
  455.     /* get the filter name and its args */
  456.         if ((s=mlreply("#", line, NLINE)) != TRUE)
  457.                 return(s);
  458.  
  459.     /* setup the proper file names */
  460.     bp = curbp;
  461.     strcpy(tmpnam, bp->b_fname);    /* save the original name */
  462.     strcpy(bp->b_fname, bname1);    /* set it to our new one */
  463.  
  464.     /* write it out, checking for errors */
  465.     if (writeout(filnam1) != TRUE) {
  466.         mlwrite("[Cannot write filter file]");
  467.         strcpy(bp->b_fname, tmpnam);
  468.         return(FALSE);
  469.     }
  470.  
  471. #if     AMIGA
  472.         newcli = Open("CON:0/0/640/200/MicroEMACS Subprocess", NEW);
  473.     strcat(line, " <ram:fltinp >ram:fltout");
  474.         Execute(line,0L,newcli);
  475.     s = TRUE;
  476.         Close(newcli);
  477.         sgarbf = TRUE;
  478. #endif
  479. #if     MSDOS
  480.     strcat(line," <fltinp >fltout");
  481.     movecursor(term.t_nrow - 1, 0);
  482.     TTkclose();
  483.         system(line);
  484.     TTkopen();
  485.         sgarbf = TRUE;
  486.     s = TRUE;
  487. #endif
  488. #if     V7 | USG | BSD
  489.         TTputc('\n');                /* Already have '\r'    */
  490.         TTflush();
  491.         TTclose();                              /* stty to old modes    */
  492.     strcat(line," <fltinp >fltout");
  493.         system(line);
  494.         TTopen();
  495.         TTflush();
  496.         sgarbf = TRUE;
  497.         s = TRUE;
  498. #endif
  499.  
  500.     /* on failure, escape gracefully */
  501.     if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) {
  502.         mlwrite("[Execution failed]");
  503.         strcpy(bp->b_fname, tmpnam);
  504.         unlink(filnam1);
  505.         unlink(filnam2);
  506.         return(s);
  507.     }
  508.  
  509.     /* reset file name */
  510.     strcpy(bp->b_fname, tmpnam);    /* restore name */
  511.     bp->b_flag |= BFCHG;        /* flag it as changed */
  512.  
  513.     /* and get rid of the temporary file */
  514.     unlink(filnam1);
  515.     unlink(filnam2);
  516.     return(TRUE);
  517. }
  518.  
  519. #if     VMS
  520. /*
  521.  * Run a command. The "cmd" is a pointer to a command string, or NULL if you
  522.  * want to run a copy of DCL in the subjob (this is how the standard routine
  523.  * LIB$SPAWN works. You have to do wierd stuff with the terminal on the way in
  524.  * and the way out, because DCL does not want the channel to be in raw mode.
  525.  */
  526. sys(cmd)
  527. register char   *cmd;
  528. {
  529.         struct  dsc$descriptor  cdsc;
  530.         struct  dsc$descriptor  *cdscp;
  531.         long    status;
  532.         long    substatus;
  533.         long    iosb[2];
  534.  
  535.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  536.                           oldmode, sizeof(oldmode), 0, 0, 0, 0);
  537.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  538.                 return (FALSE);
  539.         cdscp = NULL;                           /* Assume DCL.          */
  540.         if (cmd != NULL) {                      /* Build descriptor.    */
  541.                 cdsc.dsc$a_pointer = cmd;
  542.                 cdsc.dsc$w_length  = strlen(cmd);
  543.                 cdsc.dsc$b_dtype   = DSC$K_DTYPE_T;
  544.                 cdsc.dsc$b_class   = DSC$K_CLASS_S;
  545.                 cdscp = &cdsc;
  546.         }
  547.         status = LIB$SPAWN(cdscp, 0, 0, 0, 0, 0, &substatus, 0, 0, 0);
  548.         if (status != SS$_NORMAL)
  549.                 substatus = status;
  550.         status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  551.                           newmode, sizeof(newmode), 0, 0, 0, 0);
  552.         if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL)
  553.                 return (FALSE);
  554.         if ((substatus&STS$M_SUCCESS) == 0)     /* Command failed.      */
  555.                 return (FALSE);
  556.         return (TRUE);
  557. }
  558. #endif
  559.  
  560. #if    ~AZTEC & ~MSC & ~TURBO & MSDOS
  561.  
  562. /*
  563.  * This routine, once again by Bob McNamara, is a C translation of the "system"
  564.  * routine in the MWC-86 run time library. It differs from the "system" routine
  565.  * in that it does not unconditionally append the string ".exe" to the end of
  566.  * the command name. We needed to do this because we want to be able to spawn
  567.  * off "command.com". We really do not understand what it does, but if you don't
  568.  * do it exactly "malloc" starts doing very very strange things.
  569.  */
  570. sys(cmd, tail)
  571. char    *cmd;
  572. char    *tail;
  573. {
  574. #if MWC86
  575.         register unsigned n;
  576.         extern   char     *__end;
  577.  
  578.         n = __end + 15;
  579.         n >>= 4;
  580.         n = ((n + dsreg() + 16) & 0xFFF0) + 16;
  581.         return(execall(cmd, tail, n));
  582. #endif
  583.  
  584. #if LATTICE
  585.         return(forklp(cmd, tail, (char *)NULL));
  586. #endif
  587. }
  588. #endif
  589.  
  590. #if    MSDOS & LATTICE
  591. /*    System: a modified version of lattice's system() function
  592.         that detects the proper switchar and uses it
  593.         written by Dana Hogget                */
  594.  
  595. system(cmd)
  596.  
  597. char *cmd;    /*  Incoming command line to execute  */
  598.  
  599. {
  600.     char *getenv();
  601.     static char *swchar = "/C";    /*  Execution switch  */
  602.     union REGS inregs;    /*  parameters for dos call  */
  603.     union REGS outregs;    /*  Return results from dos call  */
  604.     char *shell;        /*  Name of system command processor  */
  605.     char *p;        /*  Temporary pointer  */
  606.     int ferr;        /*  Error condition if any  */
  607.  
  608.     /*  get name of system shell  */
  609.     if ((shell = getenv("COMSPEC")) == NULL) {
  610.         return (-1);        /*  No shell located  */
  611.     }
  612.  
  613.     p = cmd;
  614.     while (isspace(*p)) {        /*  find out if null command */
  615.         p++;
  616.     }
  617.  
  618.     /**  If the command line is not empty, bring up the shell  **/
  619.     /**  and execute the command.  Otherwise, bring up the     **/
  620.     /**  shell in interactive mode.   **/
  621.  
  622.     if (p && *p) {
  623.         /**  detect current switch character and us it  **/
  624.         inregs.h.ah = 0x37;    /*  get setting data  */
  625.         inregs.h.al = 0x00;    /*  get switch character  */
  626.         intdos(&inregs, &outregs);
  627.         *swchar = outregs.h.dl;
  628.         ferr = forkl(shell, "command", swchar, cmd, (char *)NULL);
  629.     } else {
  630.         ferr = forkl(shell, "command", (char *)NULL);
  631.     }
  632.  
  633.     return (ferr ? ferr : wait());
  634. }
  635. #endif
  636.